/**全局变量**/
var canvasWidth = 480;	//画布的宽
var canvasHeight = 650;	//画布的高

var canvas = document.getElementById('canvas');
canvas.width = canvasWidth;
canvas.height = canvasHeight;
var ctx = canvas.getContext('2d');

const PHASE_DOWNLOAD = 1;	//图片下载阶段
const PHASE_READY = 2;		//就绪阶段
const PHASE_LOADING = 3;	//游戏加载阶段
const PHASE_PLAY = 4;		//游戏进行阶段
const PHASE_PAUSE = 5;		//游戏暂停阶段
const PHASE_GAMEOVER = 6;	//游戏结束阶段

var curPhase = PHASE_DOWNLOAD;	//当前所处的阶段
var heroCount=3;
var heroScore=0;//英雄的得分

////所有的图片对象
var imgBackground;
var imgBullet1;
var imgsEnemy1=[];
var imgsEnemy2=[];
var imgsEnemy3=[];
var imgsGameLoading=[];
var imgGamePauseNor;
var imgsHero=[];
var imgStart;

/*阶段1：下载图片*/
download();  //开始下载图片

function download(){
	var progress = 0;  //下载进度
	ctx.font='80px Helvetica';//加载进度的字体大小
	ctx.fillStyle='#eee';
	function drawProgress(){
		ctx.clearRect(0,0,canvasWidth,canvasHeight);
		var txt=progress+'%';
		var w=ctx.measureText(txt).width
		ctx.fillText(txt, canvasWidth/2-w/2, canvasHeight/2+80/2);
		ctx.strokeText(txt, canvasWidth/2-w/2, canvasHeight/2+80/2);
		if(progress>=100){
			startGame();
		}
	}
	imgBackground = new Image();
	imgBackground.src = 'img/background.png';
	imgBackground.onload = function(){
		progress+=4;
		drawProgress();
	}
	imgBullet1 = new Image();
	imgBullet1.src = 'img/bullet1.png';
	imgBullet1.onload = function(){
		progress+=3;
		drawProgress();
	}
	imgsEnemy1[0]=new Image();
	imgsEnemy1[0].src="img/enemy1.png";
	imgsEnemy1[0].onload=function(){
		progress+=3;
		drawProgress();
	}
	imgsEnemy1[1]=new Image();
	imgsEnemy1[1].src="img/enemy1_down1.png";
	imgsEnemy1[1].onload=function(){
		progress+=3;
		drawProgress();
	}
	imgsEnemy1[2]=new Image();
	imgsEnemy1[2].src="img/enemy1_down2.png";
	imgsEnemy1[2].onload=function(){
		progress+=3;
		drawProgress();
	}
	imgsEnemy1[3]=new Image();
	imgsEnemy1[3].src="img/enemy1_down3.png";
	imgsEnemy1[3].onload=function(){
		progress+=3;
		drawProgress();
	}
	imgsEnemy1[4]=new Image();
	imgsEnemy1[4].src="img/enemy1_down4.png";
	imgsEnemy1[4].onload=function(){
		progress+=3;
		drawProgress();
	}
	imgsEnemy2[0]=new Image();
	imgsEnemy2[0].src="img/enemy2.png";
	imgsEnemy2[0].onload=function(){
		progress+=3;
		drawProgress();
	}
	imgsEnemy2[1]=new Image();
	imgsEnemy2[1].src="img/enemy2_down1.png";
	imgsEnemy2[1].onload=function(){
		progress+=3;
		drawProgress();
	}
	imgsEnemy2[2]=new Image();
	imgsEnemy2[2].src="img/enemy2_down2.png";
	imgsEnemy2[2].onload=function(){
		progress+=3;
		drawProgress();
	}
	imgsEnemy2[3]=new Image();
	imgsEnemy2[3].src="img/enemy2_down3.png";
	imgsEnemy2[3].onload=function(){
		progress+=3;
		drawProgress();
	}
	imgsEnemy2[4]=new Image();
	imgsEnemy2[4].src="img/enemy2_down4.png";
	imgsEnemy2[4].onload=function(){
		progress+=3;
		drawProgress();
	}
	imgsEnemy3[0]=new Image();
	imgsEnemy3[0].src="img/enemy3_n1.png";
	imgsEnemy3[0].onload=function(){
		progress+=3;
		drawProgress();
	}
	imgsEnemy3[1]=new Image();
	imgsEnemy3[1].src="img/enemy3_n2.png";
	imgsEnemy3[1].onload=function(){
		progress+=3;
		drawProgress();
	}
	imgsEnemy3[2]=new Image();
	imgsEnemy3[2].src="img/enemy3_hit.png";
	imgsEnemy3[2].onload=function(){
		progress+=3;
		drawProgress();
	}
	imgsEnemy3[3]=new Image();
	imgsEnemy3[3].src="img/enemy3_down1.png";
	imgsEnemy3[3].onload=function(){
		progress+=3;
		drawProgress();
	}	
	imgsEnemy3[4]=new Image();
	imgsEnemy3[4].src="img/enemy3_down2.png";
	imgsEnemy3[4].onload=function(){
		progress+=3;
		drawProgress();
	}	
	imgsEnemy3[5]=new Image();
	imgsEnemy3[5].src="img/enemy3_down3.png";
	imgsEnemy3[5].onload=function(){
		progress+=3;
		drawProgress();
	}	
	imgsEnemy3[6]=new Image();
	imgsEnemy3[6].src="img/enemy3_down4.png";
	imgsEnemy3[6].onload=function(){
		progress+=3;
		drawProgress();
	}	
	imgsEnemy3[7]=new Image();
	imgsEnemy3[7].src="img/enemy3_down5.png";
	imgsEnemy3[7].onload=function(){
		progress+=3;
		drawProgress();
	}
	imgsEnemy3[8]=new Image();
	imgsEnemy3[8].src="img/enemy3_down6.png";
	imgsEnemy3[8].onload=function(){
		progress+=3;
		drawProgress();
	}
	imgsGameLoading[0]=new Image();
	imgsGameLoading[0].src="img/game_loading1.png";
	imgsGameLoading[0].onload=function(){
		progress+=3;
		drawProgress();
	}
	imgsGameLoading[1]=new Image();
	imgsGameLoading[1].src="img/game_loading2.png";
	imgsGameLoading[1].onload=function(){
		progress+=3;
		drawProgress();
	}
	imgsGameLoading[2]=new Image();
	imgsGameLoading[2].src="img/game_loading3.png";
	imgsGameLoading[2].onload=function(){
		progress+=3;
		drawProgress();
	}
	imgsGameLoading[3]=new Image();
	imgsGameLoading[3].src="img/game_loading4.png";
	imgsGameLoading[3].onload=function(){
		progress+=3;
		drawProgress();
	}
	
	
	imgGamePauseNor=new Image();
	imgGamePauseNor.src="img/game_pause_nor.png";
	imgGamePauseNor.onload=function(){
		progress+=3;
		drawProgress();
	}
	imgsHero[0]=new Image();
	imgsHero[0].src="img/hero1.png";
	imgsHero[0].onload=function(){
		progress+=3;
		drawProgress();
	}
	imgsHero[1]=new Image();
	imgsHero[1].src="img/hero2.png";
	imgsHero[1].onload=function(){
		progress+=3;
		drawProgress();
	}
	imgsHero[2]=new Image();
	imgsHero[2].src="img/hero_blowup_n1.png";
	imgsHero[2].onload=function(){
		progress+=3;
		drawProgress();
	}
	imgsHero[3]=new Image();
	imgsHero[3].src="img/hero_blowup_n2.png";
	imgsHero[3].onload=function(){
		progress+=3;
		drawProgress();
	}
	imgsHero[4]=new Image();
	imgsHero[4].src="img/hero_blowup_n3.png";
	imgsHero[4].onload=function(){
		progress+=3;
		drawProgress();
	}
	imgsHero[5]=new Image();
	imgsHero[5].src="img/hero_blowup_n4.png";
	imgsHero[5].onload=function(){
		progress+=3;
		drawProgress();
	}		
	imgStart=new Image();
	imgStart.src="img/start.png";
	imgStart.onload=function(){
		progress+=3;
		drawProgress();
	}
}
/*阶段2：就绪*/
var sky;//天空对象
var logo;
function startGame(){ 
	curPhase=PHASE_READY;
	sky=new Sky(imgBackground);//创建天空对象
	logo=new Logo(imgStart);
	startEngine();//启动整个游戏的主引擎--主定时器

	//当用户点击画布，后进入下一阶段
	canvas.onclick=function(){
		if(curPhase===PHASE_READY){//从就绪阶段进入加载阶段
			curPhase=PHASE_LOADING;
			loading=new Loading(imgsGameLoading);
		}
	}
}
//天空的构造函数-使用两张图片轮换
function Sky(img){
	this.x1=0;//初始化第一张背景图坐标
	this.y1=0;
	this.x2=0;//初始化第二张背景图坐标
	this.y2=-img.height;
	this.draw=function(){//绘制天空对象
		ctx.drawImage(img,this.x1,this.y1);
		ctx.drawImage(img,this.x2,this.y2);
	}
	this.move=function(){//移动天空对象
		this.y1++;//图片坐标下移
		this.y2++;
		if(this.y1>=canvasHeight){
			this.y1=this.y2-img.height;
		}
		if(this.y2>=canvasHeight){
			this.y2=this.y1-img.height;
		}
	}
}
//游戏的主LOGO
function Logo(img){
	this.x=canvasWidth/2-img.width/2;
	this.y=canvasHeight/2-img.height/2;
	this.draw=function(){
		ctx.drawImage(img,this.x,this.y);
	}
}
/***阶段3：加载中***/
//var loading=new Loading(imgsGameLoading);
var loading;
function  Loading(imgs){
	this.x=0;
	this.y=canvasHeight-imgs[0].height;
	this.index=0;//当前要绘制的是数组中图片的下标
	this.draw=function(){
		//console.log('draw loading');
		ctx.drawImage(imgs[this.index],this.x,this.y);
	}
	this.counter=0;
	this.move=function(){
		this.counter++;
		if(this.counter%5===0){
			this.index++;//绘制下一张
			if(this.index>=imgs.length){//所有图片播放完成，则进入下一阶段
				curPhase=PHASE_PLAY;
				//进入游戏可以创建我方英雄
				hero=new Hero(imgsHero);
				bulletList=new BulletList();
				enemyList=new EnemyList();
			}
		}
	}
}
/*阶段4：游戏进行*/
var hero;
//我方英雄飞机的构造方法
function Hero(imgs){
	//我方飞机初始时出现在屏幕下方的正中央
	//console.log('draw hero');
	this.x=canvasWidth/2-imgs[0].width/2;
	this.y=canvasHeight-imgs[0].height;
	this.width=imgs[0].width;
	this.height=imgs[0].height;
	this.index=0;
	this.crashed=false;//当前是否开始撞毁程序
	this.blood=3;//英雄的血格
	this.draw=function(){
		ctx.drawImage(imgs[this.index],this.x,this.y);
	}
	this.counter=0;//move函数被调用的次数
	this.move=function(){
		this.counter++;
		if(this.counter%3===0){
			if(!this.crashed){//未开始炸毁程序
				if(this.index===0){
					this.index=1;
				}else if(this.index===1){
					this.index=0;
				}
			}else{//开始炸毁程序
				if(this.index===0||this.index===1)
					this.index=2;
				else if(this.index<imgs.length-1)
					this.index++;
				else{//撞毁程序结束，血格-1，创建新英雄
					heroCount--
					if(heroCount>0){//还有英雄
						hero=new Hero(imgsHero);
					}else{//英雄全部阵亡
						curPhase=PHASE_GAMEOVER;
					}
				}
			}
		}
		//边移动，边发射子弹
		if(this.counter%5===0){//此处的5指定每两发子弹的间隔，值越小发射越快
			this.fire();
		}
	}
	//发射子弹
	this.fire=function(){
		var b=new Bullet(imgBullet1);
		bulletList.add(b);
	}
}
canvas.onmousemove=function(){
	if(curPhase===PHASE_PLAY){
		var x=event.offsetX;
		var y=event.offsetY;
		hero.x=x-imgsHero[0].width/2;
		hero.y=y-imgsHero[0].height/2;
	}
}
//绘制当前得分和剩余英雄数量
function drawStat(){//绘制统计数据
	ctx.font='25px Helvetica';
	ctx.fillStyle='#333';
	//绘制当前的游戏得分
	var score='SCORE:'+heroScore;
	ctx.fillText(score,10,35);
	//绘制剩余的英雄数量
	var heros='HEROS:'+heroCount;
	var w=ctx.measureText(heros).width;
	ctx.fillText(heros,canvasWidth-w-10,35);
}
/*阶段5：游戏暂停*/
function Bullet(img){
	this.x=hero.x+(imgsHero[0].width/2-img.width/2);
	this.y=hero.y-img.height;
	this.width=img.width;//??
	this.height=img.height;
	this.removeble=false;//当前子弹能否删除了
	this.draw=function(){
		ctx.drawImage(img,this.x,this.y);
		//console.log('drawImage');
	}
	this.move=function(){
		this.y-=10;//此处的10指定子弹的移动速度
		//若飞出画布上边界、或打中敌机，子弹消失
		if(this.y<=-img.height){
			this.removable=true;
		}
	}
}
//子弹列表对象，其中保存着单签所有的子弹
var bulletList;
function BulletList(){
	this.arr=[];//画布上所有的子弹
	this.add=function(bullet){//添加子弹
		this.arr.push(bullet);
	}
	this.remove=function(i){//删除子弹
		this.arr.splice(i,1);
	}
	this.draw=function(){//绘制每一个子弹
		for(var i in this.arr){
			this.arr[i].draw();
		}
	}
	this.move=function(){//移动每一个子弹
		for(var i in this.arr){
			this.arr[i].move();
			if(this.arr[i].removable){
				this.remove(i);
			}
		}
	}
}
//小号敌机
function Enemy1(imgs){
	this.x=Math.random()*(canvasWidth-imgs[0].width)
	this.y=-imgs[0].height;
	this.width=imgs[0].width;
	this.height=imgs[0].height;
	this.index=0;//当前绘制的图片在数组的下标
	this.speed=7;//小敌机每42秒移动的距离--飞行的速度
	this.removable=false;//可以删除了吗？
	this.blood=1;//小敌机只有1格血
	this.crashed=false;//是否被撞毁
	this.draw=function(){
		ctx.drawImage(imgs[this.index],this.x,this.y);
	}
	this.counter=0;
	this.move=function(){
		this.counter++;
		this.y+=this.speed;
		this.checkHit();//碰撞检查
		//若飞出下边界或炸毁了，则可以删除
		if(this.crashed && this.counter%2===0){
			if(this.index===0)this.index=1;
			else if(this.index<imgs.length-1)this.index++;
			else {
				this.removable=true;
				heroScore+=3;
			}
		}
		if(this.y>=canvasHeight){//飞出下边界
			this.removable=true;
		}
	}
	//碰撞检测
	/*碰撞成功的四个条件:{obj1(物体1)obj1(物体2)}
		obj1.x+obj1.width>=obj2.x
		obj2.x+obj2.width>=obj1.x
		obj1.y+obj1.height>=obj2.y
		obj2.y+obj2.height>=obj1.y
	*/
	this.checkHit=function(){
		//每个敌机必须和我方的每个子弹/英雄进行碰撞检验
		for(var i in bulletList.arr){
			var b=bulletList.arr[i];
			//console.log(b);
			if( (this.x+this.width>=b.x)&&(b.x+b.width>=this.x)&&
				(this.y+this.height>=b.y)&&(b.y+b.height>=this.y) ){
				this.blood--;
				if(this.blood<=0){//没有血格了，开始撞毁程序
					this.crashed=true;
						
				}
				b.removable=true;
			}
		}
		//每个敌机必须和我方英雄进行碰撞检验
		if( (this.x+this.width>=hero.x)&&(hero.x+hero.width>=this.x)&&
			(this.y+this.height>=hero.y)&&(hero.y+hero.height>=this.y) ){
			hero.crashed=true;//我方英雄开始撞毁程序
		}
	}
}
//中号敌机
function Enemy2(imgs){
	this.x=Math.random()*(canvasWidth-imgs[0].width)
	this.y=-imgs[0].height;
	this.width=imgs[0].width;
	this.height=imgs[0].height;
	this.index=0;//当前绘制的图片在数组的下标
	this.speed=4;//中号敌机每42秒移动的距离--飞行的速度
	this.removable=false;//可以删除了吗？
	this.blood=10;//中号敌机只有3格血
	this.crashed=false;//是否被撞毁
	this.draw=function(){
		ctx.drawImage(imgs[this.index],this.x,this.y);
	}
	this.counter=0;
	this.move=function(){
		this.y+=this.speed;
		this.counter++;
		this.checkHit();//碰撞检查
		//若飞出下边界或炸毁了，则可以删除
		if(this.crashed && this.counter%2===0){
			if(this.index===0)this.index=1;
			else if(this.index<imgs.length-1)this.index++;
			else {
				this.removable=true;
					heroScore+=10;
			}
		}
		//若飞出下边界或炸毁了，则可以删除
		if(this.y>=canvasHeight){//飞出下边界
			this.removable=true;
		}
	}
	this.checkHit=function(){
		//每个敌机必须和我方的每个子弹/英雄进行碰撞检验
		for(var i in bulletList.arr){
			var b=bulletList.arr[i];
			//console.log(b);
			if( (this.x+this.width>=b.x)&&(b.x+b.width>=this.x)&&
				(this.y+this.height>=b.y)&&(b.y+b.height>=this.y) ){
				this.blood--;
				if(this.blood<=0){//没有血格了，开始撞毁程序
					this.crashed=true;	
				}
				b.removable=true;
			}
		}
		//每个敌机必须和我方英雄进行碰撞检验
		if( (this.x+this.width>=hero.x)&&(hero.x+hero.width>=this.x)&&
			(this.y+this.height>=hero.y)&&(hero.y+hero.height>=this.y) ){
			hero.crashed=true;//我方英雄开始撞毁程序
		}
	}
}
//大号敌机
function Enemy3(imgs){
	this.x=Math.random()*(canvasWidth-imgs[0].width)
	this.y=-imgs[0].height;
	this.width=imgs[0].width;
	this.height=imgs[0].height;
	this.index=0;//当前绘制的图片在数组的下标
	this.speed=1;//大号敌机每42秒移动的距离--飞行的速度
	this.removable=false;//可以删除了吗？
	this.blood=15;//大号敌机有15格血
	this.crashed=false;//是否被撞毁
	this.draw=function(){
		ctx.drawImage(imgs[this.index],this.x,this.y);
	}
	this.counter=0;//move()函数被调用的次数
	this.move=function(){
		this.counter++;
		this.y+=this.speed;
		this.checkHit();//碰撞检验
		if(this.counter%2===0){
			if(!this.crashed){//未开始撞毁程序
				if(this.index===0)this.index=1;
				else if(this.index===1)this.index=0;
			}else{//开始撞毁程序
				if(this.index===0||this.index===1)this.index=3;
				else if(this.index<imgs.length-1)this.index++;
				else {
					this.removable=true;
					heroScore+=50;
				}
			}
		}
		
		//若飞出下边界或炸毁了，则可以删除
		if(this.y>=canvasHeight){//飞出下边界
			this.removable=true;
		}
	}
	this.checkHit=function(){
		//每个敌机必须和我方的每个子弹/英雄进行碰撞检验
		for(var i in bulletList.arr){
			var b=bulletList.arr[i];
			//console.log(b);
			if( (this.x+this.width>=b.x)&&(b.x+b.width>=this.x)&&
				(this.y+this.height>=b.y)&&(b.y+b.height>=this.y) ){
				this.blood--;
				if(this.blood<=0){//没有血格了，开始撞毁程序
					this.crashed=true;
						
				}
				b.removable=true;
			}
		}
		//每个敌机必须和我方英雄进行碰撞检验
		if( (this.x+this.width>=hero.x)&&(hero.x+hero.width>=this.x)&&
			(this.y+this.height>=hero.y)&&(hero.y+hero.height>=this.y) ){
			hero.crashed=true;//我方英雄开始撞毁程序
		}
	}
}
//所有敌机组成的列表
var enemyList;
function EnemyList(){
	this.arr=[];//保存所有敌机
	this.add=function(enemy){//增加新敌机
		this.arr.push(enemy);
	}
	this.remove=function(i){//删除指定的敌机
		this.arr.splice(i,1);
	}
	this.draw=function(){//绘制所有的敌机
		for(var i in this.arr){
			this.arr[i].draw();
		}
	}
	this.move=function(){//让所有的敌机移动
		this.generate();//生成新的敌人
		for(var i in this.arr){
			var e=this.arr[i];
			e.move();
			if(e.removable){
				this.remove(i);
			}
		}
	}
	//随机生成一个敌机
	this.generate=function(){
		/**敌机生成的要求
		*何时生成敌机是随机的，不是定时或者连续的
		*小号敌机的概率最大，中号其次，大号最少
		*思路;0~199随机数 小号1/2/3/4/5/6 中号6/7/8 大号9 其他值不生成敌机
		*进一步拓展：可以将6,9,10设置为变量
		*/
		var num=Math.floor(Math.random()*800);
		if(num<6){
			this.add(new Enemy1(imgsEnemy1) );
		}else if(num<9){
			this.add(new Enemy2(imgsEnemy2) );
		}else if(num<10){
			this.add(new Enemy3(imgsEnemy3) );
		}
	}
}
canvas.onmouseout=function(){
	if(curPhase===PHASE_PLAY){
		curPhase=PHASE_PAUSE;
	}
}
canvas.onmouseover=function(){
	if(curPhase===PHASE_PAUSE){
		curPhase=PHASE_PLAY;
	}
}
function drawPause(){
	var x=canvasWidth/2-imgGamePauseNor.width/2;
	var y=canvasHeight/2-imgGamePauseNor.height/2;
	ctx.drawImage(imgGamePauseNor,x,y);
}
/*阶段6：游戏结束*/
function drawGameover(){
	ctx.font='50px Helvetica';
	ctx.fillStyle='#ccc';
	ctx.strokeStyle='#333';
	var txt='GAME OVER';
	var w=ctx.measureText(txt).width;
	var x=canvasWidth/2-w/2;
	var y=canvasHeight/2+50/2;
	ctx.fillText(txt,x,y);
	ctx.strokeText(txt,x,y);
}
/*游戏的主引擎-主定时器*/
function startEngine(){
	setInterval(function(){
		sky.draw();//绘制天空对象
		sky.move();//移动天空对象
		switch(curPhase){
			case PHASE_READY:
				logo.draw();
				break;
			case PHASE_LOADING:
				loading.draw();
				loading.move();
				break;
			case PHASE_PLAY:
				hero.draw();
				hero.move();
				bulletList.draw();
				bulletList.move();
				enemyList.draw();
				enemyList.move();
				drawStat();
				break;
			case PHASE_PAUSE:
				hero.draw();
				bulletList.draw();
				enemyList.draw();
				drawStat();
				drawPause();
				break;
			case PHASE_GAMEOVER:
				drawGameover();
				drawStat();
				break;
		}
	},42);//每一秒动24次(1000/24=42)
}